home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
eulisp
/
mpfeel.lha
/
MPFeel
/
Plurals
/
rectangle.emc
< prev
next >
Wrap
Lisp/Scheme
|
1992-07-05
|
9KB
|
263 lines
;
; Rectangular Paralations
;
; File : rectangle
;
; Contents : make-rectangle, N, S, E and W
;
; Description : Indeed most unprecedented hackery to create tiled
; virtual paralations which can makle use of the
; xnet of the MasPar for nearest neighbour
; Communication
;
; Author : SCM
;
; Change History
;
; Date Name Comment
; 17:06:92 SCM Created
;
#include "mp_arith.h"
(defmodule rectangle (standard0 ppl plural) ()
; SOme constant thingies
(setq global-field (make-paralation 512))
(defun list-tail (list n)
;; returns the rest of the list from element n onwards
(cond
((null list) ())
((= n 0) list)
(t (list-tail (cdr list) (- n 1)))))
(defun get-context (width height)
;; If the requested context is the global context, it uses
;; MP-Context as defined in ppl
(if (and (= width MP-X-Config) (= height MP-Y-Config)) MP-Context
(mp-make-context width height)))
(defun tile-x (w h last-ctxt)
;; Generates a list of contexts for one strip of a tiled virtual
;; processor set, if possible it reuses the previous context.
(cond
((<= w 0) ())
((< w MP-X-Config) (cons (get-context w h) ()))
(t (let ((new (if last-ctxt last-ctxt
(mp-make-context MP-X-Config h))))
(cons new (tile-x (- w MP-X-Config) h new))))))
(defun number-one (ctxt l-w g-w start)
;; Numbers one context of a tiled virtual processor set, start is
;; the value in the top-left pe, l-w is the width of the tile and
;; g-w is the width of the virtual rectangle of pes
(format t "(number-one ~a ~a ~a ~a)\n" ctxt l-w g-w start)
(let ((ofst (mp-bang ctxt 1)))
(mp-edge ctxt MP_WEST)
(mp-assign ctxt ofst (mp-bang ctxt (+ (- g-w l-w) 1)))
(mp-fi ctxt)
(mp-set ctxt ofst 0 start)
(mp-assign ctxt ofst (mp-scan-op ctxt ofst MP_PLUS))))
(defun shared-ctxt-p (ctxt-list)
;; Used to see if the next context is the same as the current one,
;; if it is we can use the current enumeration to calculate the next
;; one so it is passed to the next call of number-x
(if (null (cdr ctxt-list)) ()
(= (car ctxt-list) (cadr ctxt-list))))
(defun number-x (ctxt-list last start width left)
;; Generates enumeration plurals for one row of contexts of a tiled
;; virtual processor set. start is the value of the top left virtual
;; pe. Where the context is shared the values can be derrived from
;; the previous one.
(let ((ofst (cond
((null ctxt-list) ())
((null last)
(number-one (car ctxt-list)
(if (> left MP-X-Config) MP-X-Config left)
width start))
(t (mp-bin-op (car ctxt-list) last
(mp-bang (car ctxt-list) MP-X-Config) MP_PLUS)))))
(if (null ofst) ()
(cons ofst (number-x (cdr ctxt-list)
(if (shared-ctxt-p ctxt-list) ofst ())
(+ start MP-X-Config) width (- left MP-X-Config))))))
(defun l-tile (width height last-ctxt-list start)
;; creates a list of pairs of lists of contexts and offsets. Each of
;; the pairs represents one horizontal strip of a tiled virtual
;; processor set. These can then be turned into a list of contexts
;; and a list of offsets as used in the field/paralation format
(let ((new-ctxt-list (cond
((<= height 0) ())
((< height MP-Y-Config) (tile-x width height ()))
(t (if last-ctxt-list last-ctxt-list
(tile-x width MP-Y-Config ()))))))
(if (null new-ctxt-list) ()
(cons
(cons new-ctxt-list (number-x new-ctxt-list () start width width))
(l-tile width (- height MP-Y-Config) new-ctxt-list
(+ start (* width MP-Y-Config)))))))
(defun dispair (l)
;; Takes a list of pairs of lists and appends them all into a pair
;; of lists (which is much more useful!)
(if (null l) '(())
(let ((tmp (dispair (cdr l))))
(if (null tmp) '(())
(cons (append (caar l) (car tmp))
(append (cdar l) (cdr tmp)))))))
(defun tile (width height)
;; Produces a list of contexts and a list of offsets, which define
;; and enumerate a tiled virtual processor set.
(dispair (l-tile width height () 0)))
(defun make-rectangle (w h)
(let* ((ctxt-ofst-l-pair (tile w h))
(new-field (make-field (allocate-paralation
(car ctxt-ofst-l-pair) (* w h))
(cdr ctxt-ofst-l-pair))))
((setter index-internal) (paralation new-field) new-field)
new-field))
; Communication
; =============
; The key of our rectangular communication is a primitive function
; which performs a shift in a given direction for a row or column of a
; tiled virtual processor set. The lists of contexts and offsets
; specify a row or column in the correct order, the function does the
; shifts and handles all the edges of the tiles and wrap around. Thus
; the difficult part as far as the lisp is concerned is creating the
; right lists of contexts and offsets.
(defun partial-sub-list (l s n)
;; generates a list from l of n elements taking every s'th element
;; out of l.
(if (= n 0) ()
(cons (car l) (partial-sub-list (list-tail l s) s (- n 1)))))
(defun MP-XNET (ctxts ofsts d)
(format t "(mp-xnet ~a ~a ~a)\n" ctxts ofsts d)
(mp-xnet ctxts ofsts d))
(defun horizontal-lists (ctxts ofsts w d)
;; generates lists of contexts and offsets which reperesent
;; horizontal strips of the tiled virtual processor set. and then makes
;; the appropriate mp-xnet call
(if (null ctxts) ()
(progn
(MP-XNET (partial-sub-list ctxts 1 w) (partial-sub-list ofsts 1 w) d)
(horizontal-lists (list-tail ctxts w) (list-tail ofsts w) w d))))
(defun vertical-lists (ctxts ofsts h w c d)
;; generates lists of contexts and offsets which represent vertical
;; strips of teh tiled virtual processor set. This is a little
;; harder than the horizontal case. We stop when we have made width
;; strips, thus c(ount) starts as w(idth). The tops of the columns
;; are the first w elements of teh lists so we descend by one
;; element each time. The partial lists are made up of elements
;; w(idth) elements apart and they have h(eight) elements
(if (= c 0) ()
(progn
(MP-XNET (partial-sub-list ctxts w h) (partial-sub-list ofsts w h) d)
(vertical-lists (cdr ctxts) (cdr ofsts) h w (- c 1) d))))
; Interfacing to get
; =========== == ===
; a paralation has associated with it a vector of mappings, one for
; each direction. We place functions in these slots and put a test in
; get, if there is a function in a slot then it is applied to the
; field. We also need to know teh dimensions of the rectangle we can
; read this info from the attributes slot in the paralation structure.
(defclass rectangle-internal (paralation-internal)
()
predicate rectangle-internal-p
constructor (allocate-rectangle contexts length attributes shape))
(defun rectanglep (f) (rectangle-internal-p (paralation f)))
(defconstant Width 0)
(defconstant Height 1)
(defun make-rectangle-internal (w h)
;; at this stage all we really need to know is its width and height
;; in context tiles
(let ((dimensions (make-vector 2)))
((setter vector-ref) dimensions Width w)
((setter vector-ref) dimensions Height h)
dimensions))
(defcondition bad-paralation-class ())
(defun rectangle-width (f)
(if (rectanglep f) (vector-ref (attributes (paralation f)) Width)
(error "Not a rectangle" bad-paralation-class)))
(defun rectangle-height (f)
(if (rectanglep f) (vector-ref (attributes (paralation f)) Height)
(error "Not a rectangle" bad-paralation-class)))
(defun width (f) (/ (+ (rectangle-width f) MP-X-Config (- 1)) MP-X-Config))
(defun height (f) (/ (+ (rectangle-height f) MP-Y-Config (- 1)) MP-Y-Config))
(defun get-north (f)
(when (not (rectanglep f)) (error "Not a rectangle" bad-paralation-class))
(vertical-lists (contexts f) (offsets f) (height f) (width f)
(width f) MP_NORTH)
f)
(defun get-south (f)
(when (not (rectanglep f)) (error "Not a rectangle" bad-paralation-class))
(vertical-lists (contexts f) (offsets f) (height f) (width f)
(width f) MP_SOUTH)
f)
(defun get-east (f)
(when (not (rectanglep f)) (error "Not a rectangle" bad-paralation-class))
(horizontal-lists (contexts f) (offsets f) (width f) MP_EAST)
f)
(defun get-west (f)
(when (not (rectanglep f)) (error "Not a rectangle" bad-paralation-class))
(horizontal-lists (contexts f) (offsets f) (width f) MP_WEST)
f)
(setq rectangle-getters (make-vector 4))
(defconstant N MP_NORTH)
(defconstant S MP_SOUTH)
(defconstant E MP_EAST)
(defconstant W MP_WEST)
((setter vector-ref) rectangle-getters N get-north)
((setter vector-ref) rectangle-getters S get-south)
((setter vector-ref) rectangle-getters E get-east)
((setter vector-ref) rectangle-getters W get-west)
(defun make-rectangle (w h)
(let* ((ctxt-ofst-l-pair (tile w h))
(new-field (make-field (allocate-rectangle
(car ctxt-ofst-l-pair) (* w h)
(make-rectangle-internal w h)
rectangle-getters)
(cdr ctxt-ofst-l-pair))))
((setter index-internal) (paralation new-field) new-field)
new-field))
(export make-rectangle rectanglep rectangle-width rectangle-height N S E W)
)